<!DOCTYPE html>
<html>
<head>
  <title>定时器优化方案</title>
</head>
<body>
<script type="text/javascript">
  /**
   * TODO
   * 1, 按照时间维度归类
   * 2，应该在队列里面
   * 3，
   * @type {Object}
   */
  (function(globel) {
    const container = new WeakMap();

    class LongRequestProxy {
      constructor() {
        container.set(this, {});
      }

      // 合并请求参数
      reduce(request) {
        const requests = container.get(this);
        const { delay, id, cb } = request;
        const p = Object.create({id, cb});
        if (typeof requests[delay] !== 'object') {
          requests[delay] = {
            delay: function() {
              setInterval(() => {
                Object.values(this.requests).forEach( function(fn, index) {
                  fn()
                });
              }, delay)
            },

            requests: {}
          };

          requests[delay]['delay']()
        }

        requests[delay]['requests'] = {
          ...requests[delay]['requests'],
          [id]: cb
        };
      }

      put() {
        console.log(container.get(this))
      }
    }

    globel.LongRequestProxy = LongRequestProxy;
  })(window)

  const r = new window.LongRequestProxy();
  r.reduce({
    delay: 3000,
    id: 1,
    cb: () => console.log('cb1')
  })

  r.reduce({
    delay: 3000,
    id: 2,
    cb: () => console.log('cb2')
  })

  r.reduce({
    delay: 3000,
    id: 11,
    cb: () => console.log('cb1')
  })

  r.reduce({
    delay: 3000,
    id: 21,
    cb: () => console.log('cb2')
  })

  r.reduce({
    delay: 3000,
    id: 111,
    cb: () => console.log('cb1')
  })

  r.reduce({
    delay: 3000,
    id: 211,
    cb: () => console.log('cb2')
  })

  r.reduce({
    delay: 6000,
    id: 3,
    cb: () => console.log('cb3')
  })

  r.reduce({
    delay: 6000,
    id: 4,
    cb: () => console.log('cb4')
  })

  r.reduce({
    delay: 10000,
    id: 5,
    cb: () => console.log('c5b')
  })

  r.reduce({
    delay: 10000,
    id: 6,
    cb: () => console.log('cb5')
  })

  r.put()
</script>
</body>
</html>